package core.proto.rightwindow;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.InvalidPropertiesFormatException;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;

import core.proto.AllComponents;
import core.proto.HighlightManager;
import core.proto.InfoViz;
import core.proto.PaintDoc;
import core.proto.Util;
import core.proto.annotation.AnnotationManager;
import core.proto.annotation.AnnotationModel;
import core.proto.annotation.AnnotationUI;
import core.proto.annotation.DocAnnotationUI;
import core.proto.annotation.MapAnnotationModel;
import core.proto.annotation.MapAnnotationUI;
import core.proto.annotation.TimelineAnnotationModel;
import core.proto.annotation.TimelineAnnotationUI;
import core.proto.annotation.AnnotationModel.AnnotationLocation;
import core.proto.annotation.TimelineAnnotationModel.IntervalRow;
import core.proto.timeline.AnnotationInterval;
import core.util.logging.UserLogWriter;
import core.util.logging.constants.Action;
import core.util.logging.constants.Location;
import de.jaret.util.date.JaretDate;
import static app.constants.CollabVizConstants.*;

public class PostIt extends JInternalFrame implements Comparable<PostIt>, ActionListener, KeyListener,
MouseMotionListener, MouseListener, ChangeListener, CaretListener {

	private final PostIt thisObject = this;
	
	public static final String SHOULDSHARE = "shouldshare";
	
	//Contains the annotation which is to be highlighted for 3 seconds
	private static DocAnnotationUI timerDependent;
	private static Color noteColor = NOTE_COLOR;
	private Color thisNoteColor;
	private static boolean firstCaretUpdate = true;
	
	private JToolBar toolBar;
	public boolean miniState;
	private JTextPane area; 
	private JTextPane repArea = new JTextPane();
	private boolean select;
	private Point origin;
	public static final int SIDE_LENGTH = 200;
	private long timeCreated;
	public static final String DELIMITER = "@=-";
	private String timeStamp;

	private static final String DOCNAME = "docname";
	private static final String SESSIONID = "sid";
	private static final String OWNERTOKEN = "token";
	
	//Buttons
	JButton link;
	JButton minimize;
	JButton document;
	JButton delete;
	JButton popup;
	JButton selectPost;
	JButton unlink;
	
	public Date lastUpdateTime; 

	private String group;
	public BoardPane parent;

	public static final String DATE_FORMAT_NOW = "hh:mm:ss";

	private static long postItId = 0; // The unique postIt id to use for this run. Used to ID the postIt to the other user.  

	private Long sessionId;
	private static Object lock = new Object();

	private String ownerToken;		// Unique token of postit creator. 

	private boolean isLocalPostIt; 

	String sticky_context = "none";
	
	private HashSet<Integer> activeKeys = new HashSet<Integer>();
	
	private String docName;	// The name of the document the post it is associated with.  
	private boolean justCreated = true;
	private Point lastScreenLocation;
	public Point lastToolPos;
	private ArrayList<String> inboundList = new ArrayList<String>();
	private Color FOREIGN_NOTE_COLOR = BoardPane.getInstance().FOREIGN_NOTE_COLOR;
	
	private Properties properties; 
	private static Properties groupProperties;
	private boolean newlyAddedFromLeftWindow = false;

	private boolean justChangedLocOvetNetwork = false;
	public boolean dragEnabled = false;
	private int origX;
	private int origY;
	private Point mousePoint;
	private static int mousePointX;
	private static int mousePointY;
	private String absPath;
	boolean toDelBool = false;
	private AnnotationUI timerDependentUI;
	private static JaretDate blinkStartDate;
	private static JaretDate blinkEndDate;

	
	public boolean userTextTimerBool = false;
	private Timer timer = new Timer(0, null);
	private static boolean preventBounceBack = false;
	
	//Condition 3 variables
	private boolean foreignSharing = true;
	private boolean localSharing = true;

	PostItNetworking piNetworker;

	public PostIt(String networkString) {
		Properties p = PostIt.toProperties(networkString);
		init(PostIt.getOwnerToken(p), FOREIGN_NOTE_COLOR, (String) p.get(DOCNAME), Long.valueOf(p.getProperty(SESSIONID)));
	}

	public static String getOwnerToken(Properties prop) {
		return (String) prop.get(OWNERTOKEN);
	}

	public PostIt(String userToken, boolean newlyAddedFromLeftWindow) {
		System.out.println("inside create new postit");
		try{
			String docName;
			if(newlyAddedFromLeftWindow){
				docName = FilenameUtils.getBaseName(AllComponents.getCurrentPath());
			}
			else{
				docName="";
			}
			thisNoteColor = noteColor;
			init(userToken, noteColor, docName, nextId());
			this.newlyAddedFromLeftWindow = newlyAddedFromLeftWindow;
		}
		catch(Exception e){
			init(userToken, thisNoteColor, "", nextId());
			this.newlyAddedFromLeftWindow = newlyAddedFromLeftWindow;
		}
	}
	
	public PostIt(String userToken, String docName){
		thisNoteColor = noteColor;
		init(userToken, noteColor, docName, nextId());
		this.newlyAddedFromLeftWindow = false;
	}

	private void init(String ownerToken, Color color, String docName, long sid) {
		this.group = BoardPane.INVALID_GROUP;
		this.groupProperties = new Properties();
		this.lastScreenLocation = this.getLocation();
		this.docName = docName;
		this.ownerToken = ownerToken;
		this.isLocalPostIt = this.ownerToken.equals(InfoViz.userToken);
		if(!this.isLocalPostIt){
			thisNoteColor = FOREIGN_NOTE_COLOR;
		}
		System.out.println("SETTING SESSION ID TO " + sid);
		this.sessionId = sid;
		this.miniState = false;
		
		//Absolute path for document linking button on postIt
		absPath = FilenameUtils.getFullPathNoEndSeparator(AllComponents.getCurrentPath());
		
		area = new JTextPane();
		Dimension d = new Dimension(5,10);
		area.addMouseListener(this);
		area.addMouseMotionListener(this);
		area.setSize(d);
		area.setFocusable(false);
		area.setEnabled(false);
		area.setPreferredSize(new Dimension(120,120));
		area.setIgnoreRepaint(true);
		area.setBackground(color);
		area.setBorder(BorderFactory.createLineBorder(Color.black, 2));		
		area.setDragEnabled(true);
		area.setMargin(new Insets(5,5,5,5));
		area.setName("PostIt");
		area.setFocusable(true);

		//Set properties of the internal frame holding the post it.
		this.setBounds(0, 0, SIDE_LENGTH, SIDE_LENGTH);
		
		this.setClosable(false);
		
		this.setTitle(this.docName);
		this.setBorder(null);
		((javax.swing.plaf.basic.BasicInternalFrameUI) this.getUI()).setNorthPane(null);
		
		SimpleAttributeSet attributes = new SimpleAttributeSet();
	    StyleConstants.setBold(attributes, true);
	    StyleConstants.setUnderline(attributes, true);
		try {
			area.getDocument().insertString(0, docName, attributes);
			System.out.println("is occuring " + docName);
			attributes = new SimpleAttributeSet();
			StyleConstants.setBold(attributes, false);
			StyleConstants.setUnderline(attributes, false);
			if(!docName.equals("")){
				System.out.println("shouldn't occur " + docName);
				area.getDocument().insertString(area.getDocument().getLength(), "\n ", attributes);
			}
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		
		this.setResizable(false);
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		this.add(area);
		this.setTimeCreated(System.currentTimeMillis());
		
		updateTimestamp ();

		toolBar = new JToolBar("Still draggable");
		toolBar.addMouseMotionListener(BoardPane.getInstance());
		toolBar.addMouseListener(this);
		toolBar.setFloatable(false);
		toolBar.setRollover(true);
		
		link = new JButton();
		link.addActionListener(this);
		Icon icon = new ImageIcon(Util.getServerResource(
				"resources/img/chain.png"));
		link.setIcon(icon);
		link.setToolTipText("Connect to another sticky");
		
		minimize = new JButton();
		minimize.addActionListener(this);
		icon = new ImageIcon(Util.getServerResource(
				"resources/img/minimize.png"));
		minimize.setIcon(icon);
		minimize.setToolTipText("Minimize");
		
		document = new JButton();
		document.addActionListener(this);
		if(this.ownerToken.equals(InfoViz.UserID)){
			icon = new ImageIcon(Util.getServerResource(
					"resources/img/highlight_icon.png"));
			document.setToolTipText("Comment to the document");
		}
		else{
			icon = new ImageIcon(Util.getServerResource(
					"resources/img/highlight_person.png"));
			document.setToolTipText("Ask your partner about this");
		}
		
		document.setIcon(icon);
		
		delete = new JButton();
		delete.addActionListener(this);
		icon = new ImageIcon(Util.getServerResource(
				"resources/img/delete.png"));
		delete.setIcon(icon);
		delete.setSize(delete.getWidth() * 2, delete.getHeight());
		delete.setToolTipText("Delete");
		
		popup = new JButton();
		popup.addActionListener(this);
		icon = new ImageIcon(Util.getServerResource(
				"resources/img/popup_icon.png"));
		popup.setIcon(icon);
		popup.setToolTipText("Show pile");
		
		selectPost = new JButton();
		selectPost.addActionListener(this);
		icon = new ImageIcon(Util.getServerResource(
				"resources/img/postit_select.png"));
		selectPost.setIcon(icon);
		selectPost.setToolTipText("Select");
		
		unlink = new JButton();
		unlink.addActionListener(this);
		unlink.setToolTipText("Disable sharing sticky with partner");
		
		
		icon = new ImageIcon(Util.getServerResource(
				"resources/img/unlink.png"));
		
		if(InfoViz.postitSharingDiscretion){
			if(this.ownerToken.equals(InfoViz.UserID)){
				unlink.setSelected(true);
				
			}
			else{
				unlink.setEnabled(false);
			}
		}
		else{
			unlink.setEnabled(false);
		}
		unlink.setIcon(icon);
		
		if(InfoViz.postitSharingDiscretion && this.ownerToken.equals(InfoViz.UserID)){
		toolBar.setLayout(new FlowLayout (0, 3, 0));
		}
		else{
			toolBar.setLayout(new FlowLayout (0, 7, 0));
		}
		
		toolBar.add(document, BorderLayout.NORTH);
		toolBar.add(link, BorderLayout.NORTH);
		toolBar.add(selectPost, BorderLayout.NORTH);
		toolBar.add(minimize, BorderLayout.NORTH);
		toolBar.add(popup, BorderLayout.NORTH);
		if(InfoViz.postitSharingDiscretion && this.ownerToken.equals(InfoViz.UserID)){
			toolBar.add(unlink, BorderLayout.NORTH);
		}
		toolBar.add(delete, BorderLayout.EAST);
		
		this.add(toolBar, BorderLayout.SOUTH);
		this.addKeyListener(this);
		area.addKeyListener(this);
		area.getCaret().addChangeListener(this);
		area.addCaretListener(this);
			setLastToolDragPos();
		setupReplacementArea();
		
		setTimeStamp();
		piNetworker = new PostItNetworking(this);
		
		new Thread(
	            new Runnable() {
	                public void run() {
	                	while(true){
	                		try {
	        				InputStream in = WebUtil.pullDeleteMessage();
	        				BufferedReader data = new BufferedReader(new InputStreamReader(in)); 
	        				String deleteID = data.readLine(); 
	        				
	        				if(deleteID != null){
	        					if(deleteID.equals(thisObject.getSessionId() + "")){
	        						System.out.println("SHOULD BE DELETEING");
	        						BoardPane.getInstance().removePostIt(thisObject);
	        						thisObject.delete();
	        						thisObject.stopThread();
	        						thisObject.hide();
	        					}
	        				}
	        				
		        			} catch (IOException e1) {
		        				e1.printStackTrace();
		        			}
	                	}
	                }
	            }).start();
		
	}

	public boolean isJustChangedLocOvetNetwork () {
		return justChangedLocOvetNetwork;
	}

	public void setJustChangedLocOvetNetwork (boolean b) {
		justChangedLocOvetNetwork = b;
	}

	public boolean isNewlyAddedFromLeftWindow () {
		return newlyAddedFromLeftWindow;
	}

	public void markNotNewlyAddedFromLeftWindow () {
		newlyAddedFromLeftWindow = false;
	}

	public boolean isJustCreated() {
		return justCreated;
	}

	public void markNotJustCreated () {
		this.justCreated = false;
	}

	private void updateTimestamp () {
		this.lastUpdateTime = Calendar.getInstance().getTime();
	}

	public String getGroup (){
		return group;
	}

	public void setGroup (String group) {
		this.group = group;
	}

	public boolean isLocal () {
		return this.isLocalPostIt;
	}

	private static long nextId () {
		InputStream in;
		long id = -1;
		
		while(id == -1){
			try {
				in = WebUtil.getNextSessionId();
	
				StringWriter writer = new StringWriter();
				IOUtils.copy(in, writer); 
				String message = writer.toString();
				message = message.trim();
				
				id = Long.parseLong(message);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e){
				id = nextIdLocal();
			}
		}
		
		return id;
	}
	
	
	private static long nextIdLocal () {
		synchronized(lock) {		
			return postItId++;
		}
	}
	
	public long getID(){
		return postItId;
	}

	public long getTimeCreated() {
		return timeCreated;
	}

	public void setTimeCreated(long timeCreated) {
		this.timeCreated = timeCreated;
	}

	public String getText () {
		String out;
		try{
			out = area.getText();
		}
		catch(IndexOutOfBoundsException e){
			out = "";
		}
		
		if(out == null){
			return "";
		}
		
		return out;
	}

	public void setText (String text) {
		area.setText(text);
		this.updateTimestamp();
	}
	
	public void appendText (String text) {
		SimpleAttributeSet attributes = new SimpleAttributeSet();
	    StyleConstants.setBold(attributes, false);
		try {
			area.getDocument().insertString(area.getDocument().getLength(), text, attributes);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		
		//area.setText(area.getText() + text);
		this.updateTimestamp();
	}

	public Point getOrigin() {
		return origin;
	}

	public void setOrigin(Point origin) {
		this.origin = origin;
	}

	public JTextPane getArea() {
		return area;
	}

	//Set maximum character limit as maxChars
	public void setMaxCharacterLimit(int maxChars) {
		AbstractDocument pDoc=(AbstractDocument)area.getDocument();
		pDoc.setDocumentFilter(new DocumentSizeFilter(maxChars));
	}


	/** Return true if this node is select. */
	public boolean isSelect() {
		return select;
	}

	/** Mark this node as select. */
	public void setSelect(boolean select) {
		this.select = select;
		
		if(select){
			selectPost.setIcon(new ImageIcon (Util.getServerResource(
					"resources/img/postit_unselect.png")));
		}
		else{
			selectPost.setIcon(new ImageIcon (Util.getServerResource(
					"resources/img/postit_select.png")));
		}
	}

	/** Collected all the select nodes in list. */
	public static void getSelect(List<PostIt> list, List<PostIt> select) {
		select.clear();
		for (PostIt n : list) {
			if (n.isSelect()) {
				select.add(n);
			}
		}
	}


	/** Select each node in r. */
	public static void selectRect(List<PostIt> list, Rectangle r) {
		for (PostIt n : list) {    	  
			n.setSelect(r.intersects(n.origin.x, n.origin.y, 200, 200));
			if(n.select) {
				n.getArea().setBackground(Color.lightGray);
				n.repArea.setBackground(Color.lightGray);
			}
			else {
				n.restoreNormalColor();
			}
		}
	}
	
	public static void unselectAll(List<PostIt> list){
		for(PostIt n: list){
			n.select = false;
			n.restoreNormalColor();
		}
	}

	/** Toggle selected state of each node containing p. */
	public static void selectToggle(List<PostIt> list, Point p) {
		for (PostIt n : list) {
			if (n.contains(p)) {
				n.setSelect(!n.isSelect());
			}
		}
	}

	@Override
	/**
	 * Most recently edited come first.  
	 */
	public int compareTo(PostIt o) {
		return o.lastUpdateTime.compareTo(this.lastUpdateTime);
	}


	
	public boolean shouldShare() {
		if(unlink.isSelected()){
			return true;
		}
		return false;
	}

	public String getFontNetworkString() {
		boolean bold;
		boolean italic;
		boolean underline;
		
		String out = "";
		JTextPane p = new JTextPane();
		p.setStyledDocument(this.getArea().getStyledDocument());
		Caret c = p.getCaret();
		c.moveDot(0);
		
		if(p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Bold, true)){
			bold = true;
		}
		else{
			bold = false;
		}
		if(p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Italic, true)){
			italic = true;
		}
		else{
			italic = false;
		}
		if(p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Underline, true)){
			underline = true;
		}
		else{
			underline = false;
		}
		
		//ERIC, shoot for format biu@23|BiU@52|BIU@55   ect....
		for(int i = 0; i < area.getDocument().getLength(); i++){
			if(!(p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Bold, bold)
					&& p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Italic, italic)
					&& p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Underline, underline)) 
					|| i == area.getDocument().getLength() - 1){
				
				if(bold){
					out = out + "B";
				}else{
					out = out + "b";
				}
				if(italic){
					out = out + "I";
				}
				else{
					out = out + "i";
				}
				if(underline){
					out = out + "U";
				}
				else{
					out = out + "u";
				}
				
				if(p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Bold, true)){
					bold = true;
				}
				else{
					bold = false;
				}
				if(p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Italic, true)){
					italic = true;
				}
				else{
					italic = false;
				}
				if(p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Underline, true)){
					underline = true;
				}
				else{
					underline = false;
				}
				
				out = out + i + "|";
				
			}
				c.moveDot(i + 1);
		}
		return out;
	}

	public void setOwnerToken(String t) {
		ownerToken = t;
	}

	/**
	 * @param networkString
	 * @return Properties object containing relevant info, null if malformed. 
	 */
	public static Properties toProperties (String networkString) {
		try{
			Properties properties = new Properties();
			properties.load(IOUtils.toInputStream(networkString));
			return properties;
		} catch (IOException ioe) {
			return null;
		}
	}


	
	public String getOwner(){
		return ownerToken;
	}
	
	public String getDocName(){
		return docName;
	}
	
	public static ArrayList<String> getLinks(Properties prop, String type) {
		ArrayList<String> out = new ArrayList<String>();
		
		
		String text = prop.getProperty(type);
		
		if(!text.equals("")){
			String[] t = text.split(",");
			
			for(String s : t){
				s.replace(",", "");
				s.trim();
				if(s.length() > 0){
					s= s.substring(0, s.indexOf("|"));
					System.out.println("ADDING IN S: " + s);
					out.add(s);
				}
			}
		}
		
		return out;
	}
	
	public static ArrayList<Float> getWeights(Properties prop, String type) {
		ArrayList<Float> out = new ArrayList<Float>();
		
		String text = prop.getProperty(type);
		
		if(!text.equals("")){
			String[] t = text.split(",");
			
			for(String s : t){
				s.replace(",", "");
				s.trim();
				if(s.length() > 0){
					s= s.substring(s.indexOf("|") + 1, s.length());
					out.add(Float.parseFloat(s));
				}
			}
		}
		
		return out;
	}

	public void enableTextArea () {
		area.setEnabled(true);
	}

	public void makeEditable () {
		if (this.isLocalPostIt){
			area.requestFocusInWindow();
			area.setEnabled(true);
			area.setEditable(true);
			area.getCaret().setVisible(true);
		}
	}

	public void makeUnEditable () {
		area.setEnabled(false);
		area.setEditable(false);
		area.getCaret().setVisible(false);
		// Update the time stamp. 
		this.updateTimestamp();
	}

	public boolean isEditing () {
		return area.isEditable();
	}

	public void restoreNormalColor () {
		if (this.isLocalPostIt){
			area.setBackground(thisNoteColor);
			repArea.setBackground(thisNoteColor);
		}
		else{
			area.setBackground(FOREIGN_NOTE_COLOR);
			repArea.setBackground(FOREIGN_NOTE_COLOR);
		}
	}

	/**
	 * DEPRICATED...SEE restoretolasttoolbarlocation
	 * Set the location back to the last screen location. 
	 */
	public void restoreToLastLocation () {
		//this.setLocation(lastScreenLocation);
	}
	
	/**
	 * Sets back to previous location while using the toolbar drag method.
	 * AKA not dragging by the title bar of the postit element which was the old way.
	 */
	public void restoreToLastToolbarLocation(){
		this.setLocation(lastToolPos);
	}

	@Override
	/**
	 * Overridden to remember previous location. 
	 */
	public void setLocation(int x, int y) {
		this.lastScreenLocation = this.getLocation();
		this.setOrigin(new Point(x, y));
		super.setLocation(x,y);
	}

	@Override
	/**
	 * Overridden to remember previous location. 
	 */
	public void setLocation (Point p) {
		this.lastScreenLocation = this.getLocation();
		super.setLocation(p);
	}

	@Override
	/**
	 * Overridden to remember previous location. 
	 */
	public void setBounds (Rectangle r) {
		this.lastScreenLocation = this.getLocation();
		super.setBounds(r);
	}

	@Override
	/**
	 * Overridden to remember previous location. 
	 */
	public void setBounds (int x, int y, int w, int h) {
		this.lastScreenLocation = this.getLocation();
		
		if(y > BoardPane.getInstance().getHeight() - h){
			super.setBounds(x, BoardPane.getInstance().getHeight() - h, w, h);
		}
		else{
			super.setBounds(x, y, w, h);
		}
		
	}

	public long getSessionId () {
		return this.sessionId;
	}
	
	public void setSessionID (long s){
		sessionId = s;
	}

	@Override
	public void actionPerformed(ActionEvent e) {

		if((JButton)e.getSource() == link){
			ArrayList<PostIt> listOut = new ArrayList<PostIt>();
			
			getSelect(BoardPane.getAllPostIts(), listOut);
			
			if(this.select && listOut.size() > 1){
				BoardPane.singleLink(null, listOut);
			}
			else{
				BoardPane.singleLink(this, null);
			}
			
			UserLogWriter.stickyLog(InfoViz.UserID, Action.CONNECT, isSelf(), this.getSessionId() + "", delimText(), getGroupString(), this.sticky_context);
		}
		else if((JButton)e.getSource() == minimize){
			BoardPane.getInstance().popupEditor.setVisible(false);
			minimize();
		}
		else if((JButton)e.getSource() == document){
			findAnnotation();
			UserLogWriter.stickyLog(InfoViz.UserID, Action.DOCCONNECT, isSelf(), this.getSessionId() + "", delimText(), getGroupString(), this.sticky_context);
		}
		else if((JButton)e.getSource() == delete){
			BoardPane.getInstance().popupEditor.setVisible(false);
			UserLogWriter.stickyLog(InfoViz.UserID, Action.DELETE, isSelf(), this.getSessionId() + "", delimText(), getGroupString(), this.sticky_context);
			delete();
		}
		else if((JButton)e.getSource() == popup){
			popup(e);
		}
		else if((JButton)e.getSource() == selectPost){
			select();
		}
		else if((JButton)e.getSource() == unlink && InfoViz.postitSharingDiscretion
				&& this.ownerToken.equals(InfoViz.UserID)){
			if(unlink.isSelected()){
				this.setLocalSharing(false);
				
				unlink.setToolTipText("Enable sharing sticky with partner");
				
				LeftRightCommunicator.postItUpdated(this);
				unlink.setSelected(false);
			}
			else{
				unlink.setSelected(true);
				
				this.setLocalSharing(true);
				
				unlink.setToolTipText("Enable sharing sticky with partner");
				
				LeftRightCommunicator.postItUpdated(this);
			}
			UserLogWriter.stickyLog(InfoViz.UserID, Action.COLLABCONNECT, isSelf(), this.getSessionId() + "", delimText(), getGroupString(), this.sticky_context);
		}
		UserLogWriter.log2(Action.CLICK, Location.Whiteboard.toString(), "Sticky", "null", "null", "null", "Existing", delimText());
	}
	
	private void setLocalSharing(boolean b){
		localSharing = b;
	}
	
	public boolean getLocalSharing(){
		return localSharing;
	}
	
	public void setForeignSharing(boolean b) {
		foreignSharing = b;
	}
	
	public boolean getForeignSharing() {
		return foreignSharing;
	}
	
	/**
	 * Select button
	 */
	private void select(){
		if(!isSelect()){
			setSelect(true);
			getArea().setBackground(Color.lightGray);
			repArea.setBackground(Color.lightGray);
		}
		else{
			setSelect(false);
			restoreNormalColor();
		}
	}
	
	private void popup(ActionEvent e){
		if(!BoardPane.getInstance().popupEditor.isVisible()){
			System.out.println("popup was not visible");
			if(BoardPane.findOverlaps(this).size() > 1){
				BoardPane.getInstance().popupEditor.setVisible(true);
			}
		}
		else{
			System.out.println("popup IS visible");
			BoardPane.getInstance().popupEditor.setVisible(false);
		}
		
	}
	
	public PostIt clone(){
		PostIt newPost = new PostIt(ownerToken, false);
		newPost.setLocation(this.getLocation());
		newPost.setGroup(this.getGroup());
		newPost.setArea(this.getArea());
		newPost.timeCreated = this.timeCreated;
		newPost.timeStamp = this.timeStamp;
		newPost.absPath = this.absPath;
		newPost.thisNoteColor = thisNoteColor;
		newPost.setSessionID(this.getSessionId());
		
		ArrayList<String> inbound = new ArrayList<String>();
		for(String s : BoardPane.getInstance().groupIDMap.keySet()){
			if(BoardPane.getInstance().groupIDMap.get(s).contains(this.getGroup())){
				inbound.add(s);
			}
		}
		newPost.setInbound(inbound);
		
		return newPost;
	}
	
	private void setInbound(ArrayList<String> l){
		inboundList = l;
	}
	
	public ArrayList<String> getInbound(){
		return inboundList;
	}
	
	public void delete(){
		try {
			WebUtil.sendDeleteMessage(this.getSessionId());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e){
			
		}
		
		synchronized(BoardPane.lock){
			//this.setLocation(-1, -1);
			//Begin to save 
			HashMap<String, Object> mapOut = new HashMap<String, Object>();
				mapOut.put("singleList", BoardPane.getInstance().singleLinkMap.clone());
				mapOut.put("groups", BoardPane.getInstance().postItGroups.clone());
				HashMap<String, List<String>> groupCopy = new HashMap<String, List<String>>();
				for(String group : BoardPane.groupIDMap.keySet()){
						groupCopy.put(group, BoardPane.groupIDMap.get(group));
				}
				
				mapOut.put("groupMap",  groupCopy);
				mapOut.put("p2a",  LeftRightCommunicator.post2Anno.clone());
				mapOut.put("a2p", LeftRightCommunicator.anno2Post.clone());
			
			ArrayList<PostIt> toDelete = new ArrayList<PostIt>();
			HashSet<PostIt> toBackup = new HashSet<PostIt>();
			
			//Remove postits from boardPane
			for (PostIt postIt : BoardPane.getAllPostIts()) {
				if((postIt.select && this.select) || postIt == this){
					//Add to savestate set
					PostIt toAdd = this.clone();
					System.out.println("AREA TEXT5 " + toAdd.getText());
					toBackup.add(toAdd);
					
					AnnotationUI annoUI = LeftRightCommunicator.post2Anno.get(postIt);
					
					if(annoUI instanceof DocAnnotationUI){
						
						DocAnnotationUI docAnnoUI = (DocAnnotationUI) annoUI;
						docAnnoUI.deletehide();
						
					}
					
					if(annoUI != null){
						annoUI.deleteAnnotation();
						
						
						LeftRightCommunicator.post2Anno.remove(postIt);
						LeftRightCommunicator.anno2Post.remove(annoUI);
					}
					
					toDelete.add(postIt);
					System.out.println("AREA TEXT4 " + toAdd.getText());
				}
				
			}
			
			//SaveState
			
			mapOut.put("postSet", toBackup);
			BoardPane.getInstance().saveState("delete", mapOut);
			
			for(PostIt p : toDelete){
				BoardPane.getInstance().removePostIt(p);
			}
			
			toDelBool = true;
			
			BoardPane.getInstance().repaint();
		}
	}
	
	private void findAnnotation() {
		if(LeftRightCommunicator.post2Anno.get(this) != null){
					
			try {
				AllComponents.updateDoc(absPath + "\\" + docName + ".htm");
				
			} catch (IOException e) {
				//e.printStackTrace();
			}
			
			if(LeftRightCommunicator.post2Anno.get(this) instanceof DocAnnotationUI){

				DocAnnotationUI DA = (DocAnnotationUI) (LeftRightCommunicator.post2Anno.get(this));
				
				DA.highlightCorrespondingText(true);
				DA.changeToAltBackground();
				
				timerDependent = DA;
				
				  int delay = 3000; //milliseconds
				  ActionListener taskPerformer = new ActionListener() {
				      public void actionPerformed(ActionEvent evt) {
				    	  PostIt.endTimer();
				      }
				  };
				  
				  try{
					  MapAnnotationUI MA = (MapAnnotationUI) (LeftRightCommunicator.post2Anno.get(this));
					  MapAnnotationModel MM = (MapAnnotationModel) AnnotationManager.getModelFromUI(MA, AnnotationLocation.MAP);
					  AllComponents.setMapLocation(MM.getWaypointIconPos());
				  } catch(ClassCastException e){
					  
				  }
				  
				 Timer t = new Timer(delay, taskPerformer);
				 t.setRepeats(false);
				 t.start();
			}
			else if(LeftRightCommunicator.post2Anno.get(this) instanceof TimelineAnnotationUI){
				
				  TimelineAnnotationUI TA = (TimelineAnnotationUI) (LeftRightCommunicator.post2Anno.get(this));
				  TimelineAnnotationModel TM = (TimelineAnnotationModel) AnnotationManager.getModelFromUI(TA, AnnotationLocation.TIMELINE);
				  
				  setTimelineBlink(TM.getStart(), TM.getEnd());
				  AllComponents.timeline.repaint();
				  
				  int delay = 3000; //milliseconds
				  ActionListener taskPerformer = new ActionListener() {
				      public void actionPerformed(ActionEvent evt) {
				    	  setTimelineBlink(null, null);
				    	  AllComponents.timeline.repaint();
				      }
				  };
				  
				 Timer t = new Timer(delay, taskPerformer);
				 t.setRepeats(false);
				 t.start();
				
			}else {
				AnnotationUI DA = (AnnotationUI) (LeftRightCommunicator.post2Anno.get(this));
				timerDependentUI = DA;
				
				DA.changeToAltBackground();
				
				MapAnnotationUI MA = (MapAnnotationUI) (LeftRightCommunicator.post2Anno.get(this));
				MapAnnotationModel MM = (MapAnnotationModel) AnnotationManager.getModelFromUI(MA, AnnotationLocation.MAP);
				
				AllComponents.setMapLocation(MM.getWaypointIconPos());
				
				  int delay = 3000; //milliseconds
				  ActionListener taskPerformer = new ActionListener() {
				      public void actionPerformed(ActionEvent evt) {
				    	  timerDependentUI.revertBackground();
				      }
				  };
				  
				 Timer t = new Timer(delay, taskPerformer);
				 t.setRepeats(false);
				 t.start();
			}
			 
		}
		if(!ownerToken.equals(InfoViz.userToken)){
			
			try { 
				WebUtil.sendHighlightNotification(piNetworker.toNetworkString());			 
			} catch (SocketException e) { 
				// Can't connect to host, report it and abandon the broadcast 
				System.out.println("Can't connect to host: " + e.getMessage()); 
			} catch (FileNotFoundException e) { 
				// Servlet doesn't exist, report it and abandon the broadcast 
				System.out.println("Resource not found: " + e.getMessage()); 
			} catch (Exception e) { 
				// Some other problem, report it and abandon the broadcast 
				System.out.println("General exception: " + e.getClass().getName() + ": " + e.getMessage());
			}
		}
	}
	
	private static void setTimelineBlink(JaretDate start, JaretDate end) {
		blinkStartDate = start;
		blinkEndDate = end;
	}
	
	public static JaretDate getBlinkStartDate(){
		return blinkStartDate;
	}
	
	public static JaretDate getBlinkEndDate(){
		return blinkEndDate;
	}

	private static void endTimer(){
		timerDependent.highlightCorrespondingText(false);
		timerDependent.revertBackground();
	}

	private void setupReplacementArea(){
		//Set repArea attributes
		Dimension d = new Dimension(5,10);
		repArea.setSize(d);
		repArea.setPreferredSize(d);
		repArea.addMouseMotionListener(BoardPane.getInstance());
		repArea.addMouseListener(this);
		repArea.setFocusable(false);
		repArea.setEnabled(false);
		repArea.setPreferredSize(new Dimension(120,120));
		repArea.setIgnoreRepaint(true);
		if(select){
			repArea.setBackground(Color.LIGHT_GRAY);
		}
		else{
		repArea.setBackground(thisNoteColor);
		}
		
		repArea.setBorder(BorderFactory.createLineBorder(Color.black, 2));		
		repArea.setDragEnabled(true);
		repArea.setMargin(new Insets(5,5,5,5));
		repArea.setName("PostIt");
		repArea.setFocusable(true);
	}

	public void minimize() {
		if(miniState){
			for(PostIt p: BoardPane.getAllPostIts()){
				if((p.select && this.select) || p == this){
					p.miniState = false;
					p.setBounds(p.getX(), p.getY(), SIDE_LENGTH, SIDE_LENGTH);
					p.remove(p.repArea);
					p.area.setBounds(0, 0, SIDE_LENGTH, SIDE_LENGTH);
					p.add(p.area);
					Icon mini = new ImageIcon(Util.getServerResource(
							"resources/img/minimize.png"));
					p.minimize.setIcon(mini);
					p.minimize.setToolTipText("Minimize");
				}
				UserLogWriter.stickyLog(InfoViz.UserID, Action.MAXIMIZE, isSelf(), p.getSessionId() + "", p.delimText(), p.getGroupString(), p.sticky_context);
			}
		}
		else{
			for(PostIt p: BoardPane.getAllPostIts()){
				if((p.select && this.select) || p == this){
					Icon mini = new ImageIcon(Util.getServerResource(
							"resources/img/maximize.png"));
					p.minimize.setIcon(mini);
					
					p.miniState = true;
					p.setBounds(p.getX(), p.getY(), SIDE_LENGTH, SIDE_LENGTH / 4);
					p.remove(p.area);
					p.minimize.setToolTipText("Maximize");
					
					SimpleAttributeSet attributes = new SimpleAttributeSet();
					
					int endPos = titleEndPosition();
					
					try{
						StyleConstants.setBold(attributes, true);
					    StyleConstants.setUnderline(attributes, true);
					    p.repArea.getDocument().remove(0, p.repArea.getDocument().getLength());
						p.repArea.getDocument().insertString(0, p.area.getText(0, endPos), attributes);
					} catch (BadLocationException e) {
						e.printStackTrace();
					}
					p.add(p.repArea);
					
					this.repaint();
					BoardPane.getInstance().repaint();
					p.repArea.repaint();
					
					UserLogWriter.stickyLog(InfoViz.UserID, Action.MINIMIZE, isSelf(), p.getSessionId() + "", p.delimText(), p.getGroupString(), p.sticky_context);
				}
			}
		}
	}
	
	public int titleEndPosition(){
		return titleEndPosition(area);
	}
	
	public int titleEndPosition(JTextPane p){
		SimpleAttributeSet attributes = new SimpleAttributeSet();
		
	    StyleConstants.setBold(attributes, false);
	    StyleConstants.setUnderline(attributes, false);
			Caret c = p.getCaret();
			int curDot = c.getDot();
			c.moveDot(0);
			int endPos = 0;
			
			for(int i = 0; i < p.getDocument().getLength(); i++){
				if(p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Bold, false)
						&& p.getCharacterAttributes().containsAttribute(StyleConstants.CharacterConstants.Underline, false)){
					i = p.getDocument().getLength();
					break;
				}
				else{
					c.moveDot(i + 1);
					endPos++;
				}
			}
			
			c.moveDot(curDot);
			return endPos;
	}
	
	public int textBeginPosition(int titleEndPos){
		String examString = area.getText();
		
		String newline = System.getProperty("line.separator");
		
		for(int i = titleEndPos; i < area.getDocument().getLength(); i++){
			
			if(examString.substring(i, i).equals(newline)){
				titleEndPos++;
			}
			else if(examString.substring(i, i + 1).equals(newline)){
				titleEndPos++;
			}
			else if(examString.charAt(i) == '\n'){
				titleEndPos++;
			}
			else if(examString.substring(i + 1, i + 1).equals(newline)){
				titleEndPos++;
			}
			else if(examString.charAt(i) == ' '){
				titleEndPos++;
			}
			else if(examString.substring(i, i + 1).matches("\n")){
				titleEndPos = titleEndPos + 2;
				i++;
			}
			else if(!examString.substring(i, i + 1).matches("^\\w{1}$")){
				titleEndPos++;
			}
			else{
				break;
			}
		}
		
		return titleEndPos;
	}


	public void setTimeStamp(){
		String date = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new java.util.Date() ); 
		
		timeStamp = date;
	}
	
	public String getTimeStamp(){
		return timeStamp;
	}


	@Override
	public void keyTyped(KeyEvent e) {	}


	@Override
	public void keyPressed(KeyEvent e) {
		//Restart timer for keyboard updates
		userTextTimerBool = false;
		
		timer.stop();
		
		activeKeys.add(e.getKeyCode());
		
		int delay = 2000; //milliseconds
		  ActionListener taskPerformer = new ActionListener() {
		      public void actionPerformed(ActionEvent evt) {
		    	 userTextTimerBool = true;
		    	 UserLogWriter.stickyLog(InfoViz.UserID, Action.KEYTYPE, isSelf(), getSessionId() + "", delimText(), getGroupString(), sticky_context);
		    	 UserLogWriter.log2(Action.KEYTYPE, Location.Chat.toString(), "Sticky", "null", 
							"null", "null", "Existing", delimText());
		      }
		  };
		 timer = new Timer(delay, taskPerformer);
		 timer.setRepeats(false);
		 timer.start();
		
		if (e.getKeyCode() == KeyEvent.VK_ENTER) {
			SimpleAttributeSet attributes = new SimpleAttributeSet();
			attributes.addAttribute(StyleConstants.CharacterConstants.Bold, false);
			attributes.addAttribute(StyleConstants.CharacterConstants.Underline, false);
			
			JTextPane PIFClone = new JTextPane();
			PIFClone.setStyledDocument(this.getArea().getStyledDocument());
			if(area.getCaretPosition() == titleEndPosition(PIFClone)){		
					area.getStyledDocument().setCharacterAttributes(titleEndPosition(PIFClone), 
							1, attributes, false);
					area.setCharacterAttributes(attributes, true);
			}
		}
		else if (e.getKeyChar() != KeyEvent.CHAR_UNDEFINED && e.getKeyCode() != KeyEvent.VK_BACK_SPACE){
			SimpleAttributeSet attributes = new SimpleAttributeSet();
			if(BoardPane.getInstance().bold.isSelected()){
				attributes.addAttribute(StyleConstants.CharacterConstants.Bold, true);
			}
			if(!BoardPane.getInstance().bold.isSelected()){
				attributes.addAttribute(StyleConstants.CharacterConstants.Bold, false);
			}
			if(BoardPane.getInstance().italic.isSelected()){
				attributes.addAttribute(StyleConstants.CharacterConstants.Italic, true);
			}
			if(!BoardPane.getInstance().italic.isSelected()){
				attributes.addAttribute(StyleConstants.CharacterConstants.Italic, false);
			}
			if(BoardPane.getInstance().underline.isSelected()){
				attributes.addAttribute(StyleConstants.CharacterConstants.Underline, true);
			}
			if(!BoardPane.getInstance().underline.isSelected()){
				attributes.addAttribute(StyleConstants.CharacterConstants.Underline, false);
			}
			
			if(activeKeys.contains(KeyEvent.VK_CONTROL) && activeKeys.contains(KeyEvent.VK_C)){
				UserLogWriter.stickyLog(InfoViz.UserID, Action.KEYCOPY, isSelf(), getSessionId() + "", delimText(), getGroupString(), sticky_context);
				UserLogWriter.log2(Action.KEYCOPY, Location.Chat.toString(), "Sticky", "null", 
						"null", "null", "Existing", delimText());
			}
			else if(activeKeys.contains(KeyEvent.VK_CONTROL) && activeKeys.contains(KeyEvent.VK_V)){
				UserLogWriter.stickyLog(InfoViz.UserID, Action.KEYPASTE, isSelf(), getSessionId() + "", delimText(), getGroupString(), sticky_context);
				UserLogWriter.log2(Action.KEYPASTE, Location.Chat.toString(), "Sticky", "null", 
						"null", "null", "Existing", delimText());
			}
			
			area.setCharacterAttributes(attributes, false);
		}
	}
	
	public String delimText(){
		String out = this.getText();
		
		out = out.replace(',', '.');
		out = out.replace("\r\n", " /n ");
		return out;
	}


	@Override
	public void keyReleased(KeyEvent e) {
		activeKeys.remove(e.getKeyCode());
	}


	@Override
	public void mouseDragged(MouseEvent e) {
		for(PostIt p: BoardPane.getAllPostIts()){
			if(p == this){
				if(p == this){
					p.setLocation(p.getOrigX() + (int)(e.getXOnScreen() - p.getMousePointX()), 
							p.getOrigY() + (int)(e.getYOnScreen() - p.getMousePointY()));
				}
				else{
					p.setLocation(p.getOrigX() + (int)(e.getXOnScreen() - p.getMousePointX() ), 
							p.getOrigY() + (int)(e.getYOnScreen() - p.getMousePointY() ));
				}
			}
		}
	}


	@Override
	public void mouseMoved(MouseEvent e) {
		
	}
	
	@Override
	public void mouseClicked(MouseEvent e) {
		int numClicks = e.getClickCount();
		
		if(numClicks == 1){
			UserLogWriter.stickyLog(InfoViz.UserID, Action.CLICK, isSelf(), getSessionId() + "", delimText(), getGroupString(), sticky_context);
			UserLogWriter.log2(Action.CLICK, Location.Whiteboard.toString(), "Sticky", "null", 
					"null", "null", "Existing", delimText());
		}
		else if(numClicks > 1){
			UserLogWriter.stickyLog(InfoViz.UserID, Action.DOUBLECLICK, isSelf(), getSessionId() + "", delimText(), getGroupString(), sticky_context);
			UserLogWriter.log2(Action.DOUBLECLICK, Location.Whiteboard.toString(), "Sticky", "null", 
					"null", "null", "Existing", delimText());
		}
	}


	@Override
	public void mouseEntered(MouseEvent e) {
		UserLogWriter.stickyLog(InfoViz.UserID, Action.MOUSEENTER, isSelf(), getSessionId() + "", delimText(), getGroupString(), sticky_context);
	}


	@Override
	public void mouseExited(MouseEvent e) {
		UserLogWriter.stickyLog(InfoViz.UserID, Action.MOUSEEXIT, isSelf(), getSessionId() + "", delimText(), getGroupString(), sticky_context);
	}


	private void setLastToolDragPos (){
		lastToolPos = this.getLocation();
	}
	
	@Override
	public void mousePressed(MouseEvent e) {
		
		if(e.getSource() == area || e.getSource() == toolBar || e.getSource() == repArea){
			BoardPane.getInstance().popupEditor.setVisible(false);
			
			for(PostIt p: BoardPane.getAllPostIts()){
				if((p.isSelect() && isSelect()) || p == this){
					p.dragEnabled = true;
					p.setLastToolDragPos();
					p.origX = p.getX();
					p.origY = p.getY();
				}
			}
		
			
			mousePointX = e.getXOnScreen();
			mousePointY = e.getYOnScreen();
		}
		
		makeEditable();
	}
	
	public int getMousePointX(){
		return mousePointX;
	}
	
	public int getMousePointY(){
		return mousePointY;
	}
	
	public int getOrigX(){
		return origX;
	}
	
	public int getOrigY(){
		return origY;
	}
	
	public Point getMousePoint(){
		return mousePoint;
	}

	public boolean dragEnabled(){
		return dragEnabled;
	}

	@Override
	public void mouseReleased(MouseEvent e) {

		dragEnabled = false;
		
		System.out.println("postit dropped");
		
		synchronized(BoardPane.lock){
			//Check for overlaps now that the postit has been dropped
			if (BoardPane.getInstance().overlapsWithForbiddenAreas(this)) {
				this.setLocation(BoardPane.getInstance().getClosestGoodLocation(this));
			}
			
			List<PostIt> overlaps = new ArrayList<PostIt>();
			
			LeftRightCommunicator.postItUpdated(this);
				
			BoardPane.getInstance().determineAndAddToGroup(this, this.getLocation());
				
			overlaps = BoardPane.findOverlaps(this);
			
			if(overlaps.size() > 1){
				UserLogWriter.stickyLog(InfoViz.UserID, Action.PILE, isSelf(), getSessionId() + "", delimText(), getGroupString(), sticky_context);
			}
			else{
				UserLogWriter.stickyLog(InfoViz.UserID, Action.MOVE, isSelf(), getSessionId() + "", delimText(), getGroupString(), sticky_context);
			}
			
			try{
				//Prevent Postits in the new group other than the one moved from sending updates
				for(PostIt p: BoardPane.postItGroups.get(this.getGroup())){
					if(p.piNetworker.oldGroup.equals(p.getGroup())){
						p.piNetworker.oldNewUpdate();
					}
				}
			}
			catch(NullPointerException ex){
				
			}
			
			for(PostIt post : BoardPane.getAllPostIts()){
				if((post.isSelect() && this.isSelect()) || post == this){
					if(BoardPane.getInstance().overlapsWithForbiddenAreas(post)){
						System.out.println("MOVING BACK");
						post.setLocation(BoardPane.getInstance().getClosestGoodLocation(post));
					}
				}
			}
		}
		
		BoardPane.getInstance().repaint();
	}

	public void restoreArea(String title, String text){
		SimpleAttributeSet attributes = new SimpleAttributeSet();
	    StyleConstants.setBold(attributes, true);
	    StyleConstants.setUnderline(attributes, true);
		try {
			area.setText("");
			area.getDocument().insertString(0, title, attributes);
			attributes = new SimpleAttributeSet();
			StyleConstants.setBold(attributes, false);
			StyleConstants.setUnderline(attributes, false);
			//area.getDocument().insertString(area.getDocument().getLength(), "\n ", attributes);
			area.getDocument().insertString(area.getDocument().getLength(), text, attributes);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
	}

	public void textUpdate(String updateText) {
		//SaveState
			HashMap<String, Object> save = new HashMap<String, Object>();
			save.put("post", this);
				save.put("title", area.getText().substring(0, titleEndPosition()));
				if(area.getText().substring(titleEndPosition()) == null){
					save.put("text", "");
				}
				else{
					save.put("text", area.getText().substring(titleEndPosition()));
				}
				
			BoardPane.getInstance().saveState("textUpdate", save);
		
		String curTitle = "";
		
		try {
			curTitle = area.getText(0, titleEndPosition());
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		
		SimpleAttributeSet attributes = new SimpleAttributeSet();
	    StyleConstants.setBold(attributes, true);
	    StyleConstants.setUnderline(attributes, true);
		try {
			area.setText("");
			area.getDocument().insertString(0, curTitle, attributes);
			attributes = new SimpleAttributeSet();
			StyleConstants.setBold(attributes, false);
			StyleConstants.setUnderline(attributes, false);
			if(area.getDocument().getLength() > 0){
				area.getDocument().insertString(area.getDocument().getLength(), "\n ", attributes);
			}
			area.getDocument().insertString(area.getDocument().getLength(), updateText, attributes);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		
	}
	
	public void setArea(JTextPane a){
		area = a;
	}
	
	public static void chooseColor(Color c){
		noteColor = c;
	}
	
	public void changeThisNoteColor(Color c){
		thisNoteColor = c;
	}
	
	public static void createBullet(){
		
		JTextPane PIF = BoardPane.getInstance().postItInFocus.getArea();
		SimpleAttributeSet attributes = new SimpleAttributeSet();
		attributes.addAttribute(StyleConstants.CharacterConstants.Bold, false);
		attributes.addAttribute(StyleConstants.CharacterConstants.Underline, false);
		
		try {
			PIF.getDocument().insertString(PIF.getCaretPosition(), "\u25CF", attributes);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
	}


	@Override
	public void stateChanged(ChangeEvent e) {}
	
	public void setID(long l){
		postItId = l;
	}


	@Override
	public void caretUpdate(CaretEvent e) {	}
	
	public void preventBounceBack(boolean b) {
		System.out.println("PREVENTING BOUNCE BACK " + b);
		preventBounceBack = b;
	}

	public void stopThread(){
		piNetworker.threadRepeat = false;
	}
	
	public boolean isSelf(){
		if(this.ownerToken.equals(InfoViz.UserID)){
			return true;
		}
		else{
			return false;
		}
	}
	
	public String getGroupString(){
		String out = "{";
		boolean remove = false;
		
		for(PostIt p: BoardPane.getAllPostIts()){
			if(p.getGroup().equals(this.getGroup()) && p != this){
				out = out + p.delimText() + "-";
				remove = true;
			}
		}
		
		if(remove){
			out = out.substring(0, out.length() - 1) + "}";
		}
		else{
			out = out + "}";
		}
		
		return out;
	}
}
